package neg;

import Interaccion.NegocioBD;

import java.io.Serializable;
import java.util.ArrayList;

public class Negocio implements Serializable {

	private static final long serialVersionUID = 1L;
	private Reparto repartoActual;
	private Ubicacion direccion;
	private ArrayList<Pedido> pedidosPendientes;
	private static Negocio _instancia = NegocioBD.getBaseDeDatos();

	public Negocio(Ubicacion ubicacion) {
		this.direccion = ubicacion;
		this.repartoActual = new Reparto(direccion);
		this.pedidosPendientes = new ArrayList<Pedido>();
	}

	public void setDireccion(Ubicacion nueva) {
		this.direccion = nueva;
		this.repartoActual = new Reparto(nueva, repartoActual.getPedidos());
		guardar();
	}

	public Pedido deInicio() {
		return repartoActual.getLocal();
	}

	// Metodos de manejo de listas
	public void agregarPedidoPendiente(Pedido nuevo) {
		this.pedidosPendientes.add(nuevo);
	}

	public void quitarPedidoPendiente(Pedido p) {
		this.pedidosPendientes.remove(p);
	}

	public void agregarPedidoAProgramar(Pedido nuevo) {
		this.repartoActual.agregarPedido(nuevo);
	}

	public void eliminarPedidoAProgramar(Pedido pedido) {
		this.repartoActual.quitarPedido(pedido);
	}

	/**
	 * Metodo que modifica la instancia, reiniciando las variables relacionadas
	 * al reparto
	 * 
	 */
	public void reiniciarReparto() {
		this.repartoActual = new Reparto(direccion);
	}

	/**
	 * Metodo que retorna la lista de pedidos pendientes en forma de arreglo
	 * 
	 * @return
	 */
	public Pedido[] getArregloPedidosPendientes() {
		Pedido[] ret = new Pedido[pedidosPendientes.size()];
		for (int i = 0; i < pedidosPendientes.size(); i++)
			ret[i] = pedidosPendientes.get(i);
		return ret;
	}

	/**
	 * Metodo que retorna la lista de pedidos a programar en forma de arreglo
	 * 
	 * @return
	 */
	public Pedido[] getArregloPedidosAProgramar() {
		ArrayList<Pedido> aux = repartoActual.getPedidos();
		Pedido[] ret = new Pedido[aux.size()];
		for (int i = 0; i < aux.size(); i++)
			ret[i] = aux.get(i);
		return ret;
	}

	/**
	 * Metodo que retorna la ruta mas corta que pasa por los N pedidos de la
	 * lista de pedidos a programar
	 * 
	 * @return
	 */
	public ArrayList<Ubicacion> OptimoRecorrido() {
		ArrayList<Ubicacion> ret = new ArrayList<Ubicacion>();
		for (Pedido pedido : RecorridoOptimo())
			ret.add(pedido.getUbicacion());
		return ret;
	}

	public ArrayList<Pedido> RecorridoOptimo() {
		repartoActual.actualizarCaminoMinimo();
		return repartoActual.getCaminoMinimo();
	}

	/**
	 * Metodo que devuelve la distancia total del camino minimo (Para Test)
	 * 
	 * @return
	 */
	public double distanciaDelCaminoMinimo() {
		repartoActual.actualizarCaminoMinimo();
		return repartoActual.distanciaDelCaminoMinimo();
	}

	public void guardar() {
		NegocioBD.guardar(_instancia);
	}

	public void MostrarBaseDeDAtos() {
		NegocioBD.mostrarBaseDeDatos();
	}

	public static Negocio getInstancia() {
		return _instancia;
	}

	@Override
	public String toString() {
		return "Negocio { DIR: " + direccion + ", TODOS LOS PEDIDOS: "
				+ pedidosPendientes + ", A PROGRAMAR: "
				+ repartoActual.getPedidos() + " }";
	}

	public static void actualizarPersistencia() {
		Negocio.getInstancia().guardar();
	}
}